package auxiliary_classes;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;

import particle_simulator_chem.StdAudio;

public class BackgroundMusic implements Runnable {

	private ArrayList<URL> playlist;
	private int index;
	
	public BackgroundMusic(ArrayList<URL> playlist) {
		this.playlist = playlist;
		this.index = 0;
	}
	
	public BackgroundMusic() {
		this.playlist = new ArrayList<URL>();
	}

	@Override
	public void run() {
		
		
		for(URL filePath : playlist) {
			//Relatively small file size, larger memory consumption (~150mb for a 3:30 minute clip)
			double[] input = StdAudio.read(filePath);
			StdAudio.play(input);
			
			//Large file size, very CPU intensive. 
			/*
			try {
				Clip clip = AudioSystem.getClip();
				AudioInputStream ais = AudioSystem.getAudioInputStream(filePath);
				clip.open(ais);
				//clip.start();
			} catch (LineUnavailableException lue) {
				lue.printStackTrace();
			} catch (IOException ioe) {
				ioe.printStackTrace();
			} catch (UnsupportedAudioFileException aufe) {
				aufe.printStackTrace();
			}
			double[] fileData = StdAudio.read(filePath);
			StdAudio.play(fileData);
			*/
		}
	}
	
	public void playAll() {
		
	}
	
	/**
	 * Skips to the next audio track in the playlist. If the last track is currently being played, the first track will be played. 
	 */
	public void next() {
		StdAudio.close();
		if(this.index - 1 < this.playlist.size()) {
			this.index++;
		} else {
			index = 0;
		}
		double[] input = StdAudio.read(this.playlist.get(this.index));
		StdAudio.play(input);
	}
	
	/**
	 * Finds all File objects in the specified directory and then checks their extension against all acceptable extensions to determine type.
	 * e.g. If testConditions is {".png"}, filterDirExt will return only files ending with ".png" in their names, and thus only .png files.
	 * 
	 * @param URL dir
	 * @param boolean folder 
	 * @param String[] acceptableExtensions
	 * @return ArrayList<URL> passed
	 */
	public static ArrayList<URL> filterDirExt(URL dir, String[] acceptableExtensions) {
		ArrayList<URL> passed = new ArrayList<URL>();
		
		File dirFile;
		File[] dirFiles;
		try {
			dirFile = new File(dir.toURI());
			if(dirFile.isFile()) { 
				dirFile = dirFile.getParentFile();
			}
			
			dirFiles = dirFile.listFiles();
			for(File testFile : dirFiles) {
				for(String suffix : acceptableExtensions) {
					//System.out.println(testFile);
					if(testFile.isFile()) { 
						if(testFile.getName().substring(testFile.getName().lastIndexOf(".")).equals(suffix)) {
							passed.add(testFile.toURI().toURL());
						}
					}
				}
			}
			
		} catch (URISyntaxException use) {
			use.printStackTrace();
		} catch (NullPointerException ne) {
			ne.printStackTrace();
		} catch (MalformedURLException mue) {
			mue.printStackTrace();
		}
		
		return passed;
	}
	
	/**
	 * Shuffles the playlist.
	 * 
	 * Implementation of the Donald E. Knuth shuffling algorithm (O(n)), which is based off of the Fisher-Yates shuffle (O(n^2)).
	 * This method completely shuffles a list without bias.
	 */
	public void shuffle() { 
		int playlistSize = this.playlist.size();
		for(int i = playlistSize - 1; i > 0; i--) {
			int swapIndex = (int) Math.round(Math.random() * i);//j
			URL temp = this.playlist.get(swapIndex);
			this.playlist.set(swapIndex, this.playlist.get(swapIndex));
			this.playlist.set(i, temp);
		}
	}
	
	
	
/*|||||Getters and Setters|||||*/
	
	public void addToPlaylist(URL newURL) {
		playlist.add(newURL);
	}
	
	public ArrayList<URL> getPlaylist() {
		return this.playlist;
	}
	
	public String[] toStringArray() {
		String[] toReturn = new String[this.playlist.size()];
		for(int i = 0; i < this.playlist.size(); i++) {
			toReturn[i] = playlist.get(i).toString();
		}
		return toReturn;
	}
}
